package com.xuanzheng.company.service.impl;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonArray;
import com.xuanzheng.company.dao.AIChatDao;
import com.xuanzheng.company.dao.AIModelDao;
import com.xuanzheng.company.dao.UserDao;
import com.xuanzheng.company.dao.impl.AIChatDaoImpl;
import com.xuanzheng.company.dao.impl.AIModelDaoImpl;
import com.xuanzheng.company.dao.impl.UserDaoImpl;
import com.xuanzheng.company.entity.*;
import com.xuanzheng.company.service.AIService;
import com.xuanzheng.company.util.DBUtil;
import com.xuanzheng.company.util.IdGenerator;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.sql.*;
import java.time.Duration;
import java.time.LocalDate;
import java.util.*;

/**
 * AI服务实现类
 */
public class AIServiceImpl implements AIService {
    
    private final AIModelDao aiModelDao = new AIModelDaoImpl();
    private final AIChatDao aiChatDao = new AIChatDaoImpl();
    private final UserDao userDao = new UserDaoImpl();
    private final Gson gson = new Gson();
    private final HttpClient httpClient;
    
    public AIServiceImpl() {
        this.httpClient = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(30))
                .build();
    }
    
    @Override
     public Map<String, Object> sendChatRequest(String userId, String question) {
      return sendChatRequest(userId, question, null);
  }

  public Map<String, Object> sendChatRequest(String userId, String question, String modelId) {
      Map<String, Object> result = new HashMap<>();

      try {
          // 检查AI功能是否启用
          if (!isAIEnabled()) {
              result.put("success", false);
              result.put("message", "AI功能已被管理员禁用");
              return result;
          }

          // 获取用户信息
          User user = null;

          // 检查是否为管理员
          if (userId.startsWith("admin_")) {
              // 创建管理员用户对象
              user = new User();
              user.setId(userId);
              user.setName("系统管理员");
              user.setRole(2);
          } else {
              user = userDao.findById(userId);
          }

          if (user == null) {
              result.put("success", false);
              result.put("message", "用户不存在");
              return result;
          }

          // 检查使用限制（管理员不受限制）
          if (!userId.startsWith("admin_")) {
              AIUsageLimit usageLimit = getUserUsageLimit(userId);
              if (usageLimit != null) {
                  // 检查是否需要重置每日使用次数
                  if (!LocalDate.now().equals(usageLimit.getLastResetDate().toLocalDate())) {
                      usageLimit.setUsedToday(0);
                      usageLimit.setLastResetDate(java.sql.Date.valueOf(LocalDate.now()));
                      aiChatDao.updateUsageLimit(usageLimit);
                  }

                  if (!usageLimit.canAsk()) {
                      result.put("success", false);
                      result.put("message", "今日提问次数已用完，明天再来吧！");
                      return result;
                  }
              }
          }

          // 获取AI模型（如果指定了modelId则使用指定模型，否则使用默认模型）
          AIModel model;
          if (modelId != null && !modelId.trim().isEmpty()) {
              model = aiModelDao.findById(modelId);
              if (model == null || model.getStatus() != 1) {
                  result.put("success", false);
                  result.put("message", "指定的AI模型不可用");
                  return result;
              }
          } else {
              model = aiModelDao.findDefaultModel();
              if (model == null) {
                  result.put("success", false);
                  result.put("message", "没有可用的AI模型");
                  return result;
              }
          }

          // 创建聊天记录
          String recordId = IdGenerator.generateId();
          AIChatRecord record = new AIChatRecord();
          record.setId(recordId);
          record.setUserId(userId);
          record.setUserName(user.getName());
          record.setModelId(model.getId());
          record.setQuestion(question);
          record.setStatus(0); // 进行中

          // 保存初始记录
          aiChatDao.saveChatRecord(record);

          // 调用AI API
          String answer = callAIAPI(model, question);

          // 更新记录
          record.setAnswer(answer);
          record.setStatus(1); // 成功
          aiChatDao.updateChatRecord(record);

          // 增加使用次数（管理员不计数）
          if (!userId.startsWith("admin_")) {
              aiChatDao.incrementUsageCount(userId);
          }

          result.put("success", true);
          result.put("answer", answer);
          result.put("model", model.getName());

      } catch (Exception e) {
          e.printStackTrace();
          result.put("success", false);
          result.put("message", "处理请求时发生错误: " + e.getMessage());
      }

      return result;
  }
    
    private String callAIAPI(AIModel model, String question) throws IOException, InterruptedException {
        // 构建请求体
      Map<String, Object> requestBody = new HashMap<>();
      requestBody.put("model", model.getName()); 
      requestBody.put("max_tokens", model.getMaxTokens());
      requestBody.put("temperature", model.getTemperature());
      
      // 只有OpenAI模型支持这些参数，其他模型可能不支持
      if (model.getApiUrl().contains("openai.com") || model.getApiUrl().contains("api.openai.com")) {
          requestBody.put("top_p", 1);
          requestBody.put("presence_penalty", 0);
      }
        
        List<Map<String, String>> messages = new ArrayList<>();
        
        // 系统提示
        Map<String, String> systemMessage = new HashMap<>();
        systemMessage.put("role", "system");
        systemMessage.put("content", "You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible.");
        messages.add(systemMessage);
        
        // 用户问题
        Map<String, String> userMessage = new HashMap<>();
        userMessage.put("role", "user");
        userMessage.put("content", question);
        messages.add(userMessage);
        
        requestBody.put("messages", messages);
        
        // 构建HTTP请求
        String requestBodyJson = gson.toJson(requestBody);
        
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(model.getApiUrl()))
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer " + model.getApiKey())
                .timeout(Duration.ofSeconds(60))
                .POST(HttpRequest.BodyPublishers.ofString(requestBodyJson))
                .build();
        
        // 发送请求
        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        
        if (response.statusCode() == 200) {
            // 解析响应
            JsonObject responseJson = JsonParser.parseString(response.body()).getAsJsonObject();
            JsonArray choices = responseJson.getAsJsonArray("choices");
            if (choices != null && choices.size() > 0) {
                JsonObject message = choices.get(0).getAsJsonObject().getAsJsonObject("message");
                if (message != null) {
                    return message.get("content").getAsString();
                }
            }
            throw new RuntimeException("AI响应格式错误");
        } else {
            throw new RuntimeException("AI API调用失败，状态码: " + response.statusCode() + ", 响应: " + response.body());
        }
    }
    
    @Override
    public Map<String, Object> getUserUsageInfo(String userId) {
        Map<String, Object> info = new HashMap<>();
        
        try {
            // 对于管理员，使用无限制的使用策略
            if (userId.startsWith("admin_")) {
                AIModel defaultModel = aiModelDao.findDefaultModel();
                info.put("remainingQuestions", 9999);
                info.put("dailyLimit", 9999);
                info.put("usedToday", 0);
                info.put("currentModel", defaultModel != null ? defaultModel.getName() : "未知");
                info.put("isAdmin", true);
                return info;
            }
            
            AIUsageLimit limit = getUserUsageLimit(userId);
            AIModel defaultModel = aiModelDao.findDefaultModel();
            
            if (limit != null) {
                // 检查是否需要重置
                if (!LocalDate.now().equals(limit.getLastResetDate().toLocalDate())) {
                    limit.setUsedToday(0);
                    limit.setLastResetDate(java.sql.Date.valueOf(LocalDate.now()));
                    aiChatDao.updateUsageLimit(limit);
                }
                
                info.put("remainingQuestions", limit.getRemainingQuestions());
                info.put("dailyLimit", limit.getDailyLimit());
                info.put("usedToday", limit.getUsedToday());
            } else {
                // 创建默认限制
                int defaultLimit = getDefaultDailyLimit();
                createDefaultUsageLimit(userId, defaultLimit);
                info.put("remainingQuestions", defaultLimit);
                info.put("dailyLimit", defaultLimit);
                info.put("usedToday", 0);
            }
            
            info.put("currentModel", defaultModel != null ? defaultModel.getName() : "未知");
            info.put("isAdmin", false);
            
        } catch (Exception e) {
            e.printStackTrace();
            info.put("remainingQuestions", "未知");
            info.put("currentModel", "未知");
        }
        
        return info;
    }
    
    @Override
    public AIUsageLimit getUserUsageLimit(String userId) {
        return aiChatDao.findUsageLimitByUserId(userId);
    }
    
    @Override
    public boolean updateUserUsageLimit(String userId, int dailyLimit) {
        AIUsageLimit limit = aiChatDao.findUsageLimitByUserId(userId);
        if (limit != null) {
            limit.setDailyLimit(dailyLimit);
            return aiChatDao.updateUsageLimit(limit);
        } else {
            return createDefaultUsageLimit(userId, dailyLimit);
        }
    }
    
    private boolean createDefaultUsageLimit(String userId, int dailyLimit) {
        AIUsageLimit limit = new AIUsageLimit();
        limit.setId(IdGenerator.generateId());
        limit.setUserId(userId);
        limit.setDailyLimit(dailyLimit);
        limit.setUsedToday(0);
        limit.setLastResetDate(java.sql.Date.valueOf(LocalDate.now()));
        
        return aiChatDao.createUsageLimit(limit);
    }
    
    @Override
    public List<AIModel> getAllModels() {
        return aiModelDao.findAll();
    }
    
    @Override
    public List<AIModel> getEnabledModels() {
        return aiModelDao.findEnabledModels();
    }
    
    @Override
    public AIModel getDefaultModel() {
        return aiModelDao.findDefaultModel();
    }
    
    @Override
    public boolean addModel(AIModel model) {
        model.setId(IdGenerator.generateId());
        return aiModelDao.insert(model);
    }
    
    @Override
    public boolean updateModel(AIModel model) {
        return aiModelDao.update(model);
    }
    
    @Override
    public boolean deleteModel(String id) {
        return aiModelDao.delete(id);
    }
    
    @Override
    public boolean toggleModelStatus(String id) {
        AIModel model = aiModelDao.findById(id);
        if (model != null) {
            int newStatus = model.getStatus() == 1 ? 0 : 1;
            return aiModelDao.updateStatus(id, newStatus);
        }
        return false;
    }
    
    @Override
    public Map<String, Object> getSystemSettings() {
        Map<String, Object> settings = new HashMap<>();
        
        try (Connection conn = DBUtil.getConnection()) {
            String sql = "SELECT setting_key, setting_value FROM ai_system_setting";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery();
            
            while (rs.next()) {
                String key = rs.getString("setting_key");
                String value = rs.getString("setting_value");
                
                switch (key) {
                    case "default_daily_limit":
                        settings.put("defaultDailyLimit", value);
                        break;
                    case "default_model_id":
                        settings.put("defaultModelId", value);
                        break;
                    case "ai_enabled":
                        settings.put("aiEnabled", value);
                        break;
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        return settings;
    }
    
    @Override
    public boolean updateSystemSetting(String key, String value) {
        try (Connection conn = DBUtil.getConnection()) {
            // 开始事务
            conn.setAutoCommit(false);
            
            // 更新系统设置
            String sql = "UPDATE ai_system_setting SET setting_value = ?, update_time = CURRENT_TIMESTAMP " +
                        "WHERE setting_key = ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, value);
            pstmt.setString(2, key);
            
            int updatedRows = pstmt.executeUpdate();
            
            // 如果更新的是默认每日限制，需要同步更新所有使用默认值的用户
            if ("default_daily_limit".equals(key) && updatedRows > 0) {
                int newLimit = Integer.parseInt(value);
                
                // 更新所有使用默认限制的用户（即没有在 ai_usage_limit 表中的用户）
                // 首先为所有没有限制记录的用户创建记录
                String insertSql = "INSERT INTO ai_usage_limit (id, user_id, daily_limit, used_today, create_time, last_reset_date) " +
                                  "SELECT ?, u.id, ?, 0, CURRENT_TIMESTAMP, CURDATE() " +
                                  "FROM user u " +
                                  "WHERE u.id NOT IN (SELECT user_id FROM ai_usage_limit) " +
                                  "AND u.role IN (0, 1)"; // 只包括普通用户和公司负责人
                
                // 为每个新用户生成唯一ID
                PreparedStatement insertStmt = conn.prepareStatement(
                    "SELECT u.id FROM user u WHERE u.id NOT IN (SELECT user_id FROM ai_usage_limit) AND u.role IN (0, 1)"
                );
                ResultSet rs = insertStmt.executeQuery();
                
                PreparedStatement singleInsertStmt = conn.prepareStatement(
                    "INSERT INTO ai_usage_limit (id, user_id, daily_limit, used_today, create_time, last_reset_date) " +
                    "VALUES (?, ?, ?, 0, CURRENT_TIMESTAMP, CURDATE())"
                );
                
                while (rs.next()) {
                    String userId = rs.getString("id");
                    String limitId = IdGenerator.generateId();
                    singleInsertStmt.setString(1, limitId);
                    singleInsertStmt.setString(2, userId);
                    singleInsertStmt.setInt(3, newLimit);
                    singleInsertStmt.executeUpdate();
                }
                
                // 然后更新所有现有的限制记录为新的默认值
                // 注意：这里假设所有现有记录都应该更新为新的默认值
                // 如果需要区分自定义限制和默认限制，需要在数据库中添加标志字段
                String updateSql = "UPDATE ai_usage_limit SET daily_limit = ? " +
                                  "WHERE user_id IN (SELECT id FROM user WHERE role IN (0, 1))";
                PreparedStatement updateStmt = conn.prepareStatement(updateSql);
                updateStmt.setInt(1, newLimit);
                updateStmt.executeUpdate();
            }
            
            // 提交事务
            conn.commit();
            return updatedRows > 0;
            
        } catch (SQLException | NumberFormatException e) {
            e.printStackTrace();
            try (Connection conn = DBUtil.getConnection()) {
                conn.rollback();
            } catch (SQLException rollbackEx) {
                rollbackEx.printStackTrace();
            }
        }
        
        return false;
    }
    
    @Override
    public List<Map<String, Object>> searchUsers(String keyword) {
        List<Map<String, Object>> users = new ArrayList<>();
        
        try (Connection conn = DBUtil.getConnection()) {
            String sql = "SELECT u.id, u.name, u.phone, aul.daily_limit, aul.used_today " +
                        "FROM user u LEFT JOIN ai_usage_limit aul ON u.id = aul.user_id " +
                        "WHERE u.name LIKE ? OR u.id LIKE ? ORDER BY u.create_time DESC LIMIT 20";
            
            PreparedStatement pstmt = conn.prepareStatement(sql);
            String searchPattern = "%" + keyword + "%";
            pstmt.setString(1, searchPattern);
            pstmt.setString(2, searchPattern);
            
            ResultSet rs = pstmt.executeQuery();
            while (rs.next()) {
                Map<String, Object> user = new HashMap<>();
                user.put("id", rs.getString("id"));
                user.put("name", rs.getString("name"));
                user.put("phone", rs.getString("phone"));
                user.put("dailyLimit", rs.getObject("daily_limit"));
                user.put("usedToday", rs.getObject("used_today"));
                users.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        return users;
    }
    
    private boolean isAIEnabled() {
        try (Connection conn = DBUtil.getConnection()) {
            String sql = "SELECT setting_value FROM ai_system_setting WHERE setting_key = 'ai_enabled'";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery();
            
            if (rs.next()) {
                return "1".equals(rs.getString("setting_value"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        return true; // 默认启用
    }
    
    private int getDefaultDailyLimit() {
        try (Connection conn = DBUtil.getConnection()) {
            String sql = "SELECT setting_value FROM ai_system_setting WHERE setting_key = 'default_daily_limit'";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery();
            
            if (rs.next()) {
                return Integer.parseInt(rs.getString("setting_value"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        return 10; // 默认限制
    }
}